/*
 * 
 * Libman
 * 
 * Daniel Kaufmann, Martin Lang, Simon Moosbrugger,
 * Stefan Mayer, Stephan Halbeisen
 * 
 */
package application.server.interlending;

import java.rmi.RemoteException;
import java.rmi.server.ServerNotActiveException;
import java.util.List;

import javax.jms.JMSException;
import javax.naming.NamingException;

import middleware.datacontainer.searchclient.ExemplarContainer;
import model.User;
import application.controller.server.SessionController;
import application.controller.server.UseCaseControllerExemplarLoan;
import application.controller.server.UseCaseControllerMediumReserve;
import application.controller.server.UseCaseControllerMediumSearch;
import application.exceptions.ClientNotFoundException;
import application.exceptions.DatabaseException;
import application.exceptions.ExemplarAlreadyLend;
import application.exceptions.ExemplarNotFoundException;
import application.exceptions.InsufficientClientRightsException;
import application.exceptions.MediumNotFoundException;
import application.exceptions.ReserveNotAllowedException;
import application.exceptions.SessionException;
import application.exceptions.UserNotInDbException;
import application.exceptions.WrongCredentialsException;
import application.server.jms.MyProducer;

/**
 * The Class ServerImpl.
 */
public class ServerImpl extends ServerPOA {

	/**
	 * The Thread CheckSessions is for checking all 2 hours for expired session
	 * If session is expired, it will removed from HashMap
	 */
	private class CheckSessions extends Thread {

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Thread#run()
		 */
		public void run() {
			while (true) {
				try {
					Thread.sleep(1000 * 60 * 60 * 2);
					_sc.checkSessions();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 7928519965220352313L;

	/** The _sc. */
	private static SessionController _sc;

	/**
	 * Instantiates a new server impl.
	 * 
	 * @throws RemoteException
	 *             the remote exception
	 */
	public ServerImpl() throws RemoteException {
		super();

		if (_sc == null) {
			_sc = new SessionController();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see application.server.Server#login(java.lang.String, java.lang.String)
	 */
	public String login(String username, String password) {
		try {
			return _sc.login(username, password, "");
		} catch (WrongCredentialsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DatabaseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UserNotInDbException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see application.server.Server#checkSession(java.lang.String)
	 */
	public void logout(String sessionid) {
		_sc.logout(sessionid);
	}

	@Override
	public void reserve(String sessionId, int mediumID) {
		User user = _sc.getUser(sessionId);
		
		try {
			(new UseCaseControllerMediumReserve()).reserve(sessionId, "", user
					.getClient().getId(), mediumID);
		} catch (DatabaseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MediumNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClientNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ReserveNotAllowedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SessionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InsufficientClientRightsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	@Override
	public MediumContainer[] searchMedium(
			String searchText) {
		return null;
	}

	public void loanMedium(String sessionId, int exemplarId) {
		User user = _sc.getUser(sessionId);
		try {
			(new UseCaseControllerExemplarLoan()).loanMedium(sessionId, "",
					exemplarId, user.getClient().getId());
			MyProducer.getInstance().sendMessage("Exemplar " + exemplarId + 
									" is loanded from " + user.getClient().getId());
		} catch (ClientNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExemplarNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExemplarAlreadyLend e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DatabaseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SessionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InsufficientClientRightsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServerNotActiveException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JMSException e){
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NamingException e){
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public application.server.interlending.ExemplarContainer[] getExemplars(
			int mediumID) {
		try {
			List<ExemplarContainer> list = (new UseCaseControllerMediumSearch())
					.getExemplars(mediumID);
			application.server.interlending.ExemplarContainer[] arr = new application.server.interlending.ExemplarContainer[list
					.size()];
			for (int i = 0; i < list.size(); i++) {
				ExemplarContainer con = list.get(i);
				application.server.interlending.ExemplarContainer ex = new application.server.interlending.ExemplarContainer(
						con.getId(), con.getInvno(), con.getLoaned());
				arr[i] = ex;
			}
			return arr;
		} catch (MediumNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExemplarNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}
